<?php

namespace App\Ad\Docking;

use App\Ad\MediaApi\MediaApiBase;
use App\Commons\CommonConstant;
use App\Datalog\AdMonitorLog;
use App\Models\AdMonitor;
use App\Models\AdPlan;
use App\Models\FirstupAd;
use App\Models\Firstups;
use App\Models\Log\LogAdMonitor;
use App\Models\Log\LogAdMonitorInfo;
use App\Models\Log\LogAdPostbackMedia;
use Illuminate\Http\Request;
use YQ\YqExtend;

// 今日头条-小程序推广
class ToutiaoMicroGame extends DockingBase
{
    // 点击监控参数
    protected $monitorParams = [
        'promotion_id'   => '__PROMOTION_ID__',     // 广告id
        'promotion_name' => '__PROMOTION_NAME__',   // 广告名称
        'project_id'     => '__PROJECT_ID__',       // 项目id
        'project_name'   => '__PROJECT_NAME__',     // 项目名称
        'mid1'           => '__MID1__',             // 图片素材id
        'mid2'           => '__MID2__',             // 标题素材id
        'mid3'           => '__MID3__',             // 视频素材id
        'mid4'           => '__MID4__',             // 试玩素材id
        'mid5'           => '__MID5__',             // 落地页素材id
        'mid6'           => '__MID6__',             // 安卓下载详情页素材id
        'advertiser_id'  => '__ADVERTISER_ID__',    // 广告主id
        'csite'          => '__CSITE__',            // 广告投放位置
        'convert_id'     => '__CONVERT_ID__',       // 转化id
        'request_id'     => '__REQUEST_ID__',       // 请求下发的id
        'track_id'       => '__TRACK_ID__',         // 请求下发的id&创意id的md5,16位
        'sl'             => '__SL__',               // 请求的语言
        'imei'           => '__IMEI__',             // 安卓的设备 ID 的 md5 摘要，32位
        'idfa'           => '__IDFA__',             // IOS 6+的设备id字段，32位
        'idfa_md5'       => '__IDFA_MD5__',         // IOS 6+的设备id的md5摘要，32位
        'android_id'     => '__ANDROIDID__',        // 安卓id原值的md5，32位
        'oaid'           => '__OAID__',             // Android Q及更高版本的设备号，32位
        'oaid_md5'       => '__OAID_MD5__',         // Android Q及更高版本的设备号的md5摘要，32位
        'os'             => '__OS__',               // 操作系统平台
        'mac'            => '__MAC__',              // 移动设备mac地址,转换成大写字母,去掉“:”，并且取md5摘要后的结果
        'mac1'           => '__MAC1__',             // 移动设备mac地址,转换成大写字母,去掉“:”，并且取md5摘要后的结果
        'ip'             => '__IP__',               // 正常情况下，全量下发IPv4地址。极少数情况如IPV4无法取数，则下发 IPv6
        'ua'             => '__UA__',               // 用户代理
        'geo'            => '__GEO__',              // 位置信息，包含三部分:latitude（纬度），longitude（经度）以及precise（确切信息,精度）
        'ts'             => '__TS__',               // 客户端发生广告点击事件的时间，以毫秒为单位时间戳
        'callback_param' => '__CALLBACK_PARAM__',   // 一些跟广告信息相关的回调参数，内容是一个加密字符串，在调用事件回传接口的时候会用到
        'callback_url'   => '__CALLBACK_URL__',     // 直接把调用事件回传接口的url生成出来，广告主可以直接使用
        'model'          => '__MODEL__',            // 手机型号
        'union_site'     => '__UNION_SITE__',       // 对外广告位编码
        'caid'           => '__CAID__',             // 中国广告协会互联网广告标识，包含最新两个版本的CAID和版本号，url encode之后的json字符串
    ];

    // 转化类型映射
    protected $eventTypeMap = [
        CommonConstant::EVENT_FIRSTUP => '0',
        CommonConstant::EVENT_REG     => '1',
        CommonConstant::EVENT_PAY     => '2',
    ];

    // 此接口由子类继承
    // 获得点击监控链接拼接参数
    public function getMonitorParams($device_type): string
    {
        return http_build_query($this->monitorParams);
    }

    // 此接口由子类继承
    // 处理落地监控数据
    public function handleMonitorInfo(Request $request)
    {
        // 待匹配日志
        $params           = $request->all();
        $log              = LogAdMonitor::suffix(date('Ym'));
        $log->create_time = time();
        $log->plan_id     = $params['plan_id'];
        $log->ip          = $params['ip'] ?? '';
        $log->click_id    = $params['request_id'];
        $log->save();

        // 完整日志
        $info              = LogAdMonitorInfo::suffix(date('Ym'));
        $info->create_time = time();
        $info->plan_id     = $params['plan_id'];
        $info->monitor_id  = $log->id;
        $info->data        = json_encode($params, JSON_UNESCAPED_UNICODE);
        $info->save();

        // 落地日志
        AdMonitorLog::getInstance()->addLog($log, $info);

        return yqok();
    }

    /**
     * 此接口由子类继承
     * 根据媒体加密方式-生成对应的设备码，用于匹配
     * @param int      $device_type 设备类型
     * @param string[] $device_nums 设备码
     * @return array
     */
    public function getMonitorDeviceNum($device_type, $device_nums): array
    {
        $data = [];
        foreach ($device_nums as $key => $val) {
            switch ($key) {
                case 'click_id':
                    $data[$key] = $val;
                    break;
            }
        }

        return $data;
    }

    /**
     * 此接口由子类继承
     * 将用户行为进行api上报转化，如激活注册付费
     * 文档地址：https://bytedance.feishu.cn/docx/doxcnsCqXkvxoAg36GDzkRRRuAq
     * @param int $event_type 事件类型 如激活注册付费
     * @param AdMonitor $monitor
     * @param FirstupAd $firstup_ad
     * @param mixed $mod 事件对应的模型 激活 Firstup 注册 Users 付费 Orders
     * @return int 处理结果状态
     */
    public function postbackToMedia($event_type, AdMonitor $monitor, FirstupAd $firstup_ad, $mod): int
    {
        // 此事件不需要上报
        if (!isset($this->eventTypeMap[$event_type])) {
            return LogAdPostbackMedia::STATUS_NONEED;
        }

        $plan = AdPlan::find($firstup_ad->plan_id);
        if ($plan['access_type'] != AdPlan::ACCESS_TYPE_API) {
            return LogAdPostbackMedia::STATUS_NOTAPI;
        }

        $monitor_data = json_decode($monitor->data, true);
        // $firstups     = Firstups::where('click_id', $monitor_data['request_id'] ?? 0)->first();
        $firstups     = Firstups::find($firstup_ad->firstup_id);
        if (!$firstups) {
            return LogAdPostbackMedia::STATUS_NOMONITOR;
        }

        $params = [
            'clue_token' => (string)$firstups->clue_token ?? '',
            'open_id'    => (string)$firstups->openid ?? 0,
            'event_type' => (string)$this->eventTypeMap[$event_type],
        ];

        $is_pay = $event_type == CommonConstant::EVENT_PAY;
        if ($is_pay) {
            $params['props']['pay_amount'] = intval($mod->call_money * 100);
        }

        $url       = 'https://clue.oceanengine.com/outer/wechat/applet/token/1766119313125379';
        $token     = '32C70444420705909DDBEB8DB74D70D6';
        $nonce     = YqExtend::getRandomInt(4);
        $timestamp = $mod->create_time;

        $collect = [$token, strval($nonce), strval($timestamp)];
        usort($collect,'strcmp');
        $signature = sha1(implode('',$collect));

        $url .= "?timestamp={$timestamp}&nonce={$nonce}&signature={$signature}";
        $res  = MediaApiBase::getInstance()->curl($url, json_encode($params), true, true);
        if ($res[0] != 200) {
            return LogAdPostbackMedia::STATUS_FAIL;
        }

        return LogAdPostbackMedia::STATUS_SUCC;
    }

    // 此接口由子类继承
    // 匹配成功后补齐监控数据
    public function supplementMonitorInfo(FirstupAd $firstup_ad, AdMonitor $monitor)
    {
        $data = json_decode($monitor->data, true);

        $firstup_ad->advertiser_id  = $data['advertiser_id'] ?? 0;    // 广告主id
        $firstup_ad->project_id     = $data['project_id'] ?? 0;       // 项目id
        $firstup_ad->promotion_id   = $data['promotion_id'] ?? 0;     // 广告id
        $firstup_ad->project_name   = $data['project_name'] ?? '';    // 项目名称
        $firstup_ad->promotion_name = $data['promotion_name'] ?? '';  // 广告名称
        $firstup_ad->mid3           = $data['mid3'] ?? '';            // 视频素材ID
        $firstup_ad->request_id     = $data['request_id'] ?? '';      // 请求下发id
    }
}
